package com.myrpc.handler;

import com.myrpc.provider.InterfaceProvider;
import com.myrpc.transfer.dto.RpcRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * RPC请求处理器
 */
@Slf4j
@Component(value = "RpcRequestHandler")
@DependsOn({"DefaultInterfaceProvider"})
public class RpcRequestHandler {
    @Autowired
    private InterfaceProvider interfaceProvider;

    /**
     * 拦截 Rpc 请求并进行执行
     * @param rpcRequest rpc请求
     * @return 执行结果
     */
    public Object handle(RpcRequest rpcRequest){
        //得到需要执行的目标对象
        String interfaceName = rpcRequest.getInterfaceName();
        String[] split = interfaceName.split("\\$\\$");
        interfaceName = split[0];
        Object targetObject = interfaceProvider.getInterfaceByName(interfaceName);
        if (targetObject == null){
            throw new RuntimeException("无法得到需要执行的目标Bean对象");
        }
        Object result;
        try {
            //得到需要执行的目标方法
            Method targetMethod = targetObject.getClass().getDeclaredMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes());
            //取消安全检查
            targetMethod.setAccessible(true);
            //执行目标方法
            result = targetMethod.invoke(targetObject, rpcRequest.getParameters());
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return result;
    }
}
